/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gfdclient;

import guiautorization.AutorizationWindow;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
//import java.io.FileReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.rmi.RemoteException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
//import java.util.logging.Level;
//import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.xml.ws.handler.LogicalHandler;
import networkservice.PingNetService;
import networkservice.ReconnectPingService;
import repository.exception.FileSizeException;
import repository.exception.RepositorySizeException;
import userservercontroller.IAutorizationClient;
import userservercontroller.IRepositoryClient;
import userservercontroller.WrongKeyExeption;
//import javax.swing.UIManager;
import repository.ByteArray;
import java.io.UnsupportedEncodingException;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.JPopupMenu;
/**
 * @author Aleksey ID = 2001
 * @author Truewar Ashman (<a href="mailto:truewar@hotmail.ru">truewar@hotmail.ru</a>) ID = 2009
 * @author Tielvar ID = 1004
 * @version 0.2
 * 
 * правил Richi ID = 1017 Добавлена переменная для контекстного меню menuPopup
 */
public class MainFrame extends JFrame {
    /** ширина по умолчанию */
    public static final int DEFAULT_WIDTH=500;
    /** высота по умолчанию */
    public static final int DEFAULT_HEIGHT=500;
    /** диалоговое окно авторизации */
    private AutorizationWindow dlgConnect;
    /** диалоговое окно выбора файлов */
    private JFileChooser dlgChooser;    
    /** диалоговое окно "о проекте" */
    private AboutDialog dlgAbout;
    /** текстовое окно сообщений */
    private JTextArea txtMsg;
    /** текстовое окно редактирования файлов */
    private JTextArea txtSource;
    /** список файлов */
    //private JList treeFiles;  // исправлено ID=1008
    private JRepositoryTree treeFiles;
    /** модель для списка файлов */
    private DefaultListModel modeltreeFiles;
    /** разделитель между левой и правой панелями */
    private JSplitPane paneSVertical;
    /** разделитель между нижней панелью и верхними панелями */
    private JSplitPane paneSHorisontal;
    /** вкладки левой панели */
    private JTabbedPane paneTLeft;
    /** вкладки правой панели */
    private JTabbedPane paneTRight;
    /** вкладки нижней панели */
    private JTabbedPane paneTBottom;
    /** левая панель */
    private JPanel panelLeft;
    /** правая панель */
    private JPanel panelRight;
    /** нижняя панель */
    private JPanel panelBottom;
    /** панель строки состояния */
    private JPanel panelStatusBar;
    /** панель управления */
    private JToolBar barMain;
    /** строка меню */
    private JMenuBar menuBar;
    /** меню "Файл" */
    private JMenu menuFile; 
    /** меню "Сеть" */
    private JMenu menuLan; 
    /** меню "Помощь" */
    private JMenu menuHelp;
    /** контекстное меню */
    private JPopupMenu menuPopup;
    /** полоса прокрутки для содержимого левой панели */
    private JScrollPane scrollLeft;
    /** полоса прокрутки для содержимого правой панели */
    private JScrollPane scrollRight;
    /** полоса прокрутки для содержимого нижней панели */
    private JScrollPane scrollBottom;
    /** текст строки состояния */
    private JLabel lblStatusBar;
    /** картинка со статусом соединения */
    private JLabel lblConnectStatus;
    /** ссылка на текущий просматриваемый файл*/
    private File curFile=null;
	/** Набор кодировок */
	public JEncodingComboBox encoding;
    /** Внутренняя логика */
    private InnerLogic innerLogic;
    /** кнопка панели инструментов для установления соединения */
    private JButton btnConnect;
    /** кнопка панели инструментов для разрыва соединения */
    private JButton btnDisconnect;
    /** обработчик разрыва соединения */
    private ReconnectPingService reconnectPingService;

	/**
	 * Вектор для хранения данных из файлов.
	 * Каждый элемент вектора соответствует вкладки.
	 */
	private Vector <String> fileBuf;
	/** Вектор кнопок, удаляющих вкладки */
	private Vector<JButton> TabVector;
    /**
     * Обработчик пункта меню "О программе"
     */
    class AboutAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            dlgAbout.setVisible(true);
        }
    }

    class CreateFolderAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            try {
                String str=treeFiles.createFolder();
                if(str==null) msg("Директория уже существует");
                else msg("Создана директория "+str);
            } catch (RemoteException ex) { //обрыв соединения
                reconnectPingService.doReaction();
            } catch (IOException ex) {
                msg("Не удалось создать директорию");
            } catch (WrongKeyExeption ex) { //ошибка ключа
                reconnectPingService.doReaction();
            } catch (NullPointerException ex){
				if(innerLogic.getAutorizationKey() == -1)
					msg("Соединение не установлено.");
				else
					msg("Невозможно создать директорию.");
			}
        }
    }

    class UpdateAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            try {
                treeFiles.updateFileList();
            } catch (RemoteException ex) { //обрыв соединения
                reconnectPingService.doReaction();
            } catch (WrongKeyExeption ex) { //ошибка ключа
                reconnectPingService.doReaction();
            } catch (NullPointerException ex){
				if(innerLogic.getAutorizationKey() == -1)
					msg("Соединение не установлено.");
				else
					msg("Невозможно обновить список файлов.");
			}
        }
    }


    /**
     * РћР±СЂР°Р±РѕС‚С‡РёРє РїСѓРЅРєС‚Р° РјРµРЅСЋ "РЎРѕРµРґРёРЅРµРЅРёРµ"
     */
    class ConnectAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            dlgConnect.setVisible(true);
            if(dlgConnect.getResult()) {
              //pingService.startPing();
              setConnectStatus(true); //изменить картинку соединения
              setStatusBarText("Установлено сетевое соединение");
              //скрыть кнопку "соединение" и показать "отключения"
              //barMain.getComponentAtIndex(3).setVisible(false);
              msg("Соединение с сервером " + dlgConnect.getInetAddress() + " выполнилось успешно");
              try{
              treeFiles.init(innerLogic.getUSC(), innerLogic.getAutorizationKey());
              }catch(Exception ee){}
            }
        }
    }
    /**
     * Обработчик пункта меню "Соединение"
     */
    class LogoffAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            try {
                IAutorizationClient auth = innerLogic.getUSC();
                if (auth != null){
                    setConnectStatus(false); //изменить картинку соединения
                    setStatusBarText("Соединение разорвано пользователем");      
                    if (auth.logoff(innerLogic.getAutorizationKey())){
                        msg("авторизация отменена, вы успешно вышли.");
                    }       
                }
                else msg("Соединение не установлено!");
            } catch (RemoteException ex) {/*  msg("Ошибка соединения");*/ }
            innerLogic.disconnectServer();
        }
    }
    
    /**
     * Обработчик пункта меню "Выход"
     */
    class ExitAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }
    }
    
	/**
	 * Обработчик тыка по вкладке
	 */
	class TabListener implements ChangeListener {
		@Override
		public void stateChanged(ChangeEvent e) {
			if(paneTRight.getTabCount() == 0) {
				if(fileBuf.size() != 0) msg("Рассогласование вектора данных и панели вкладок");
				txtSource.setText("");
				encoding.setSelectedIndex(-1);
				return;
			}
			int sel = paneTRight.getSelectedIndex();
			String tmp = fileBuf.get(sel);
			JPanel p = (JPanel) paneTRight.getTabComponentAt(sel);
			String g;
			if(p == null) g = treeFiles.getLastSelectedPathComponent().toString();
			else g = ((JLabel) p.getComponent(0)).getText();
			String ext[] = g.split("\\.");
			String encd = encoding.getEncodingByExtension(ext[ext.length-1]);

			try
			{
				if(encd == null)
					encd = encoding.set.getField("default");

				txtSource.setText(new String(tmp.getBytes(), encd));
				encoding.setSelectedIndex(encd);
			} catch(UnsupportedEncodingException ex)
			{
				txtSource.setText(String.valueOf(tmp.getBytes()));
			}catch(Exception ex)
			{
			}
			
			
			//txtSource.setText(fileBuf.elementAt(paneTRight.getSelectedIndex()));
		}
	}
	
    /**
     * Обработчик смены кодировки
     */
    class EncodingListener implements ItemListener {
        @Override
        public void itemStateChanged(ItemEvent event)
		{
		/** +modified by TrueWar (2009), at 24.03.09
		 * Обновление метода в связи с изменением файла настроек.
		 */
			if(encoding.isEnabled() == true)
			{
				if(fileBuf.size() == 0) return;
				int sel = paneTRight.getSelectedIndex();
				String ext[] = ((JLabel)((JPanel) paneTRight.getTabComponentAt(sel))
						.getComponent(0)).getText().split("\\.");
				encoding.changeEncoding(encoding.getSelectedItem().toString(), ext[ext.length-1]);
				encoding.saveSettingsToFile();

				String tmp = fileBuf.get(paneTRight.getSelectedIndex());
				try
				{
					String encd = encoding.getSelectedItem().toString();
					txtSource.setText(new String(tmp.getBytes(), encd));
					encoding.setSelectedIndex(encd);
				} catch(UnsupportedEncodingException ex)
				{
					txtSource.setText(String.valueOf(tmp.getBytes()));
				}catch(Exception ex)
				{
				}
            }
        }
    }

    /**
     * Обработчик пункта меню "Импорт файлов"
     */
    class ImportAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            //настройка диалогового окна
            File tmpFile = new File(".");
            dlgChooser.setCurrentDirectory(tmpFile);
            dlgChooser.setMultiSelectionEnabled(true);
            int result = dlgChooser.showOpenDialog(null);
            //успешный выбор
            if(result==JFileChooser.APPROVE_OPTION){
                //выранные файлы
                File[] resFiles = dlgChooser.getSelectedFiles();
                //зарегестрированные в системе файлы
                /*Vector<File> importedFiles = innerLogic.getFiles();
                int i,j;
                //проверить совпадение файлов
                for(i=0;i<resFiles.length;i++){
                    //сравнить с уже импортированными
                    for(j=0;j<importedFiles.size();j++){
                        if(resFiles[i].getPath().equals(
                                importedFiles.get(j).getPath())==true ){
                            msg("Файл "+resFiles[i].getPath()+" импортирован ранее");
                            resFiles[i]=tmpFile; // поставить заглушку
                            continue;
                        }
                    }
                }
                //импортировать новые
                for(i=0;i<resFiles.length;i++){
                    if(resFiles[i]==tmpFile) continue; //пропустить заглушку
                    importedFiles.add(resFiles[i]);
                    modeltreeFiles.addElement(resFiles[i].getName());
                    msg("Импортрован Файл: "+resFiles[i].getPath());
                }
                */
                //передача фалов в дерево
                // !!! ДОВЕСТИ ДО УМА СООБЩЕНИЯ (подставлять допустимые размеры
                // !!! при перехвате *SizeException)
                for(File f:resFiles)
                    try {
                        String str=treeFiles.importFile(f);
                        if(str==null) {msg("Не выбрана директория"); break;}
                        else msg("Импортрован Файл: "+f.getPath()+" в "+str);
                    } catch (RemoteException ex) { //обрыв соединения
                        reconnectPingService.doReaction();
                    } catch (IOException ex) {
                        msg("Не удалось импортровать Файл: "+f.getPath());
                    } catch (FileSizeException ex) {
                        msg("Файл превысил допустимый размер: "+f.getPath());
                    } catch (RepositorySizeException ex) {
                        msg("Превышен допустимый размер репозитория");
                        break;
                    } catch (WrongKeyExeption ex){ //ошибка ключа
                        msg("Обрыв соединения, ожидайте производится попытка переподключения");
                        reconnectPingService.doReaction();
                    }catch (NullPointerException ex){
						if(innerLogic.getAutorizationKey() == -1)
							msg("Соединение не установлено.");
						else
							msg("Не выбрана директория.");
					}
					
            }
            //произошла ошибка
            else if(result==JFileChooser.ERROR_OPTION){
                JOptionPane.showMessageDialog(null, 
                        "Возникла непредвиденная ошибка", 
                        "Ошибка",  JOptionPane.ERROR_MESSAGE);
            }
        }
    }
    
    /**
     * Обработчик пункта меню "Исключить файл"
     */
    class RemoveAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            /*int [] sel=treeFiles.getSelectionRows();
            Vector<File> importedFiles = innerLogic.getFiles();
            if(sel.length==0)
            msg("Не выбран файл для исключения");
            else{ //удалить зарегестрированные файлы
            //удаление в обратном порядке для сохранения индексов
            for(int i=sel.length-1;i>=0;i--){
            //исключение просматриваемого
            if(curFile==importedFiles.get(sel[i])){
            curFile=null;
            txtSource.setText("");
            paneTRight.setTitleAt(0, "Просмотр файла");
            encoding.setSelectedIndex(-1);
            encoding.setEnabled(false);
            }
            msg("Файл "+importedFiles.get(sel[i]).getPath()+" исключен");
            importedFiles.remove(sel[i]);
            modeltreeFiles.remove(sel[i]);
            }
            }*/
            try {
                 String str=treeFiles.delete();
                 if(str==null) msg("Не выделен элемент для удаления");
                 else msg("Удален элемент: "+str);
            } catch (RemoteException ex) { //обрыв соединения
                reconnectPingService.doReaction();
            } catch (WrongKeyExeption ex) {
                reconnectPingService.doReaction();
            }
        }
    }
    
    /**
     * Обработчик событий мыши для списка файлов
     */
    class ListMouseAction extends MouseAdapter{
        @Override
        public void mouseClicked(MouseEvent evt){
            //обработка двойного щелчка
//            if(evt.getClickCount()==2) fileView();
        }
    }
    	
    /**
     * Обработчик пункта меню "Просмотр файла"
     */
    class ViewAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            try {
                //запросить файл
                ByteArray buffer=treeFiles.getFile();
                if(buffer==null){
                    msg("Не выделен элемент для чтения");
                    return;
                }
              //  encoding.setSelectedIndex(-1);
                //преобразовать массив байт в строку и вывести в поле
                String str = new String(buffer.getAll());
				fileBuf.add(str);
				/** +modified by TrueWar (2009), at 24.03.09
				 * Обновление метода в связи с изменением файла настроек.
				 */
				
				/*New tab:*/
				paneTRight.addTab(null, null);
				JPanel tab = new JPanel();
				final JButton a = new JButton(new ImageIcon("pict/close_8.png"));
                a.setBorderPainted(false);
                a.setOpaque(false);
				//Dimension closeButtonSize = new Dimension(16,16);
				//a.setPreferredSize(closeButtonSize);
				a.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						for(int i = paneTRight.getTabCount()-1; i >= 0; i--) {
							Component cmp = paneTRight.getTabComponentAt(i);
							if(cmp == a.getParent()){
								fileBuf.remove(i);
								paneTRight.removeTabAt(i);
								TabVector.remove(i);
								break;
							}
						}		
					}
				});
				TabVector.add(a);
				JLabel tabLabel = new JLabel(
						treeFiles.getLastSelectedPathComponent().toString());
				tab.add(tabLabel/*, BorderLayout.WEST*/);
				tab.add(a/*, BorderLayout.EAST*/);
				tab.setOpaque(false);
				paneTRight.setTabComponentAt(paneTRight.getTabCount()-1, tab);
				
				
				
/* <!TODO> Перенести на элемент закрытия вкладки, после их появления!!!	/*/
				//if(fileBuf.size() > 0) fileBuf = new Vector <String> ();/*/
/*************************************************************************/
                //изменить текст вкладки
                //paneTRight.setTitleAt(0,
                //        treeFiles.getLastSelectedPathComponent().toString());
				
                //txtSource.setText(str);
				
            } catch (RemoteException ex) { //обрыв соединения
                reconnectPingService.doReaction();
            } catch (WrongKeyExeption ex) { //обрыв соединения
                reconnectPingService.doReaction();
            } catch (IOException ex) {
                msg("Ошибка при чтении файла " +
                        treeFiles.getLastSelectedPathComponent().toString());
            }catch (NullPointerException ex){
				if(innerLogic.getAutorizationKey() == -1)
					msg("Соединение не установлено.");
				else
					msg("Не выбран файл.");
			}
        }
    }
    
    /**
     * Обработчик пункта меню "Отправить файлы"
     */
    /*class SendAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            Vector<File> importedFiles = innerLogic.getFiles();
            if(importedFiles.size()==0) 
                msg("Нет файлов для отправки");
            else{
                //передать файлы                    
                msg("Эта опция пока что не реализована");
        }
    }}*/

    /**
     * Обработчик пункта меню "Вычислить"
     */
    class ExecuteAction extends AbstractAction{
        public void actionPerformed(ActionEvent e){
            //запросить путь до выделенного файла
			String str = treeFiles.getSelectedObjectPath();
			msg("Запрос на выполнение файла "+str);
            try{
            innerLogic.getUSC().addTask( innerLogic.getAutorizationKey(),
                    true, null, str, null);
            }catch(RemoteException re){
             msg("Соединение не установлено");
            }
		}
	}
    /**
     * Обработчик пункта меню "Откомпилировать"
     */
    class CompilAction extends AbstractAction{
        public void actionPerformed(ActionEvent e){
            //запросить путь до выделенного файла
			String str = treeFiles.getSelectedObjectPath();
            String strExe;
            //изменить расширение на exe
            int dotPos=str.lastIndexOf(".");
            if(dotPos==-1) strExe=str+".exe";
            else strExe = str.substring(0, dotPos)+".exe";
			msg("Запрос на компиляцию файла "+str);
            try{
                innerLogic.getUSC().addTask( innerLogic.getAutorizationKey(),
                    false, str, strExe, null);
            }catch(RemoteException re){
                msg("Соединение не установлено");
            }
		}
	}

    /**
     * Обработчик пункта меню "Скачать"
     */
    class DownloadAction extends AbstractAction{
        public void actionPerformed(ActionEvent e){
            try {
                //проверить выбор файла
                if(treeFiles.getLastSelectedPathComponent()==null ||
                        ((DefaultMutableTreeNode)treeFiles.
                        getLastSelectedPathComponent()).
                        getAllowsChildren()==true){
                    msg("Не выделен файл для скачивания");
                    return;
                }
                //открыть окно сохранения файла
                JFileChooser chooser = new JFileChooser();
                //вставить имя файла в репозитории
                chooser.setSelectedFile(new File(treeFiles.getSelectedObjectPath()));
                int result = chooser.showSaveDialog(null);
                //успешный выбор
                if(result==JFileChooser.APPROVE_OPTION){
                    //запросить файл
                    ByteArray buffer=treeFiles.getFile();
                    if(buffer==null){
                        msg("Ошибка при скачивании файла");
                        return;
                    }
                    //создать файловый поток
                    FileOutputStream out = new FileOutputStream
                            (chooser.getSelectedFile().getPath());
                    try{
                        //записать файл
                        out.write(buffer.getAll());
                    }finally{out.close();} //закрыть поток
                }
            } catch (Exception ex){
                msg("Ошибка при скачивании файла");
            }
        }
    }
    /**
     * создание основного окна
     */
    public MainFrame(){
        //установить стиль
        try{
            UIManager.setLookAndFeel( new com.nilo.plaf.nimrod.NimRODLookAndFeel());
            SwingUtilities.updateComponentTreeUI(this);
        }catch(Exception e) {
            e.printStackTrace();
        }
        //настройка окна
        setTitle("GFD Клиент");
        setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
        //центрирование окна
        Toolkit kit = Toolkit.getDefaultToolkit();
        Dimension screenSize = kit.getScreenSize();
        setLocation(
                (screenSize.width - DEFAULT_WIDTH)/2, 
                (screenSize.height - DEFAULT_HEIGHT)/2);
        setIconImage(kit.getImage("./pict/client.png"));
        //создание элементов управления и диалоговых окон
        innerLogic = new InnerLogic(this);
        reconnectPingService = new ReconnectPingService(innerLogic);
        CreateDialog();
        CreateControl();
        ConfigurateControl();
        ConfigurateActions();      
        //прочие настройки GUI
        msg("Система запущена в автономном режиме");
        setConnectStatus(false);
        setStatusBarText("Сетевое соединение не установлено");
        paneTLeft.addTab("Файлы", null);
        paneTBottom.addTab("Журнал",null);

		this.setVisible(true);
		paneSHorisontal.setDividerLocation(0.3);
		paneSVertical.setDividerLocation(0.7);
        //paneTRight.addTab("Просмотр файла", 
        //        new ImageIcon("pict/docs_16.gif"), null);

        //Инициализация сервиса для пинга
        //pingService = new PingNetService(innerLogic);

    }
    
    /**
     * создание диалоговых окон
     */
    private void CreateDialog(){
        dlgConnect = new AutorizationWindow(this,innerLogic);
        dlgAbout = new AboutDialog(this, true);
        dlgChooser = new JFileChooser();
    }
    
    /**
     * создание элементов управления основного окна
     * 
     * правил Richi ID = 1017 создаем эелемент контекстного меню menuPopup
     */
    private void CreateControl(){
        //инициализация элементов управления
        modeltreeFiles = new DefaultListModel();
        //treeFiles = new JList(modeltreeFiles);

        treeFiles = new JRepositoryTree();
        txtMsg = new JTextArea();
        txtSource = new JTextArea();
        lblStatusBar = new JLabel();
        lblConnectStatus = new JLabel();
        //вкладки
        paneTLeft = new JTabbedPane();
        paneTRight = new JTabbedPane();
        paneTBottom = new JTabbedPane();
        //панели
        panelLeft = new JPanel();
        panelRight = new JPanel();
        panelBottom = new JPanel();
        panelStatusBar = new JPanel();
        //панель управления
        barMain = new JToolBar();
        //меню
        menuFile = new JMenu("Файл");
        menuLan = new JMenu("Сеть");
        menuHelp = new JMenu("Помощь");
        menuBar = new JMenuBar();
        // контекстное меню
        menuPopup = new JPopupMenu();
        //разделители
        paneSHorisontal = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                panelLeft,panelRight);
        paneSVertical = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
                paneSHorisontal,panelBottom);

        //полосы прокрутки
        scrollLeft = new JScrollPane(treeFiles);
        scrollRight = new JScrollPane(txtSource);
        scrollBottom = new JScrollPane(txtMsg);
		encoding = new JEncodingComboBox();
	//	try{
		encoding.setEnabled(true);
		encoding.getEncodings();
		encoding.updateGUIList();
//            encoding.load();
        encoding.setSelectedIndex(-1);
		fileBuf = new Vector <String> ();
//		} catch (IOException ex){
//            msg("Невозможно прочитать файл настроек");
//		}
		TabVector = new Vector<JButton>();
	}
	
    /**
     * первичная настройка элементов управления и вывод на панель
     * 
     * правил Richi ID = 1017
     * добавление к панели paneTLeft контекстного меню
     */
    private void ConfigurateControl(){
        //настройка панелей
        panelLeft.setLayout(new BorderLayout());
        panelLeft.add(paneTLeft,BorderLayout.NORTH);
        panelLeft.add(scrollLeft,BorderLayout.CENTER);
        panelRight.setLayout(new BorderLayout());
        panelRight.add(paneTRight,BorderLayout.NORTH);
		panelRight.add(encoding,BorderLayout.SOUTH);
        panelRight.add(scrollRight,BorderLayout.CENTER);
        panelBottom.setLayout(new BorderLayout());
        panelBottom.add(paneTBottom,BorderLayout.NORTH);
        panelBottom.add(scrollBottom,BorderLayout.CENTER);
        //настройка вкладок
        paneTLeft.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
        paneTRight.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
        paneTBottom.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
        //настройка разделителей
        paneSVertical.setOneTouchExpandable(true);
        paneSHorisontal.setOneTouchExpandable(true);
        //настройка остальных элементов
        txtMsg.setEditable(false);
        txtSource.setEditable(false);
        panelStatusBar.add(lblConnectStatus);
        panelStatusBar.add(lblStatusBar);
        treeFiles.addMouseListener(new ListMouseAction());
        //меню
        menuBar.add(menuFile);
        menuBar.add(menuLan);
        menuBar.add(menuHelp);
        setJMenuBar(menuBar);
        panelStatusBar.setLayout(new FlowLayout(FlowLayout.LEFT));
        //вывод элементов
        add(barMain,BorderLayout.NORTH); //строка меню
        add(panelStatusBar,BorderLayout.SOUTH); //строка состояния
        add(paneSVertical,BorderLayout.CENTER); //содержимое
        // контекстное меню от Richi
        paneTLeft.setComponentPopupMenu(menuPopup);
    }
    
    /**
     * Настройка действий панели и меню
     *  правил Richi ID = 1017 наполнение контекстного меню menuPopup,
     *  создание элемента actionPaste
     */
    private void ConfigurateActions(){
        //соединение
        Action actionConnect = new ConnectAction();
        actionConnect.putValue(Action.NAME, "Соединение");
        actionConnect.putValue(Action.SMALL_ICON, 
                new ImageIcon("pict/connect_16.png"));
        actionConnect.putValue(Action.LARGE_ICON_KEY, 
                new ImageIcon("pict/connect_32.png"));
        actionConnect.putValue(Action.SHORT_DESCRIPTION, "Соединение");
        //разрыв соединения
        Action actionLogoff = new LogoffAction();
        actionLogoff.putValue(Action.NAME, "Отключиться");
        actionLogoff.putValue(Action.SHORT_DESCRIPTION, "Отмена авторизации");
        actionLogoff.putValue(Action.SMALL_ICON,
                new ImageIcon("pict/disconnect_16.png"));
        actionLogoff.putValue(Action.LARGE_ICON_KEY,
                new ImageIcon("pict/disconnect_32.png"));
        //выход   
        Action actionExit = new ExitAction();
        actionExit.putValue(Action.NAME, "Выход");
        actionExit.putValue(Action.SHORT_DESCRIPTION, "Выход");
        //О программе
        Action actionAbout = new AboutAction();
        actionAbout.putValue(Action.NAME, "О программе");
        actionAbout.putValue(Action.SMALL_ICON, 
                new ImageIcon("pict/info_16.png"));
        actionAbout.putValue(Action.LARGE_ICON_KEY, 
                new ImageIcon("pict/info_32.png"));
        actionAbout.putValue(Action.SHORT_DESCRIPTION, "О программе");
        //Импорт файлов
        Action actionFileImport = new ImportAction();
        actionFileImport.putValue(Action.NAME, "Импорт файлов");
        actionFileImport.putValue(Action.SMALL_ICON, 
                new ImageIcon("pict/newfile_16.png"));
        actionFileImport.putValue(Action.LARGE_ICON_KEY, 
                new ImageIcon("pict/newfile_32.png"));
        actionFileImport.putValue(Action.SHORT_DESCRIPTION, "Импортировать файлы");
        //создать папку
        Action actionCreateFolder = new CreateFolderAction();
         actionCreateFolder.putValue(Action.NAME, "Создать директорию");
         actionCreateFolder.putValue(Action.SMALL_ICON,
                new ImageIcon("pict/newdir_16.png"));
         actionCreateFolder.putValue(Action.LARGE_ICON_KEY,
                new ImageIcon("pict/newdir_32.png"));
         actionCreateFolder.putValue(Action.SHORT_DESCRIPTION, "создать каталог в репозитории");
        //обновить репозиторий
        Action actionUpdateRepository = new UpdateAction();
         actionUpdateRepository.putValue(Action.NAME, "Обновить файловую панель");
         actionUpdateRepository.putValue(Action.SMALL_ICON,
                new ImageIcon("pict/update_16.png"));
         actionUpdateRepository.putValue(Action.LARGE_ICON_KEY,
                new ImageIcon("pict/update_32.png"));
         actionUpdateRepository.putValue(Action.SHORT_DESCRIPTION, "Обновить файловую панель");
        //Р?СЃРєР»СЋС‡РµРЅРёРµ С„Р°Р№Р»РѕРІ
        Action actionFileRemove = new RemoveAction();
        actionFileRemove.putValue(Action.NAME, "Удалить файл");
        actionFileRemove.putValue(Action.SMALL_ICON, 
                new ImageIcon("pict/delete_16.png"));
        actionFileRemove.putValue(Action.LARGE_ICON_KEY, 
                new ImageIcon("pict/delete_32.png"));
        actionFileRemove.putValue(Action.SHORT_DESCRIPTION, "Исключить файл");
        //Просмотр файла
        Action actionFileView = new ViewAction();
        actionFileView.putValue(Action.NAME, "Просмотреть файл");
        actionFileView.putValue(Action.SMALL_ICON, 
                new ImageIcon("pict/view_16.png"));
        actionFileView.putValue(Action.LARGE_ICON_KEY, 
                new ImageIcon("pict/view_32.png"));
        actionFileView.putValue(Action.SHORT_DESCRIPTION, "Просмотреть файл");
        //Отправить файлы
        /*Action actionFileSend = new SendAction();
        actionFileSend.putValue(Action.NAME, "Отправить файлы");
        actionFileSend.putValue(Action.SMALL_ICON, 
                new ImageIcon("pict/go_16.gif"));
        actionFileSend.putValue(Action.LARGE_ICON_KEY, 
                new ImageIcon("pict/go_32.gif"));
        actionFileSend.putValue(Action.SHORT_DESCRIPTION, "Отправить файлы");*/

		//Отправить файлы на выполнение
        Action actionExecute = new ExecuteAction();
        actionExecute.putValue(Action.NAME, "Выполнить");
        actionExecute.putValue(Action.SMALL_ICON,
                new ImageIcon("pict/calc_16.png"));
        actionExecute.putValue(Action.LARGE_ICON_KEY,
                new ImageIcon("pict/calc_32.png"));
        actionExecute.putValue(Action.SHORT_DESCRIPTION, "Выполнить");
        //Отправить файлы на компиляцию
        Action actionCompil = new CompilAction();
        actionCompil.putValue(Action.NAME, "Компилировать");
        actionCompil.putValue(Action.SMALL_ICON,
                new ImageIcon("pict/compil_16.png"));
        actionCompil.putValue(Action.LARGE_ICON_KEY,
                new ImageIcon("pict/compil_32.png"));
        actionCompil.putValue(Action.SHORT_DESCRIPTION, "Компилировать");
        //скачать файл
        Action actionDownload = new DownloadAction();
        actionDownload.putValue(Action.NAME, "Скачать файл");
        actionDownload.putValue(Action.SMALL_ICON,
                new ImageIcon("pict/download_16.png"));
        actionDownload.putValue(Action.LARGE_ICON_KEY,
                new ImageIcon("pict/download_32.png"));
        actionDownload.putValue(Action.SHORT_DESCRIPTION, "Скачать файл");
        // вставить скопированный файл в дерево (от Richi)
        Action actionPaste = new PasteAction();
        actionPaste.putValue(Action.NAME, "Вставить");
        actionPaste.putValue(Action.SHORT_DESCRIPTION, "Вставить");
        //добавить действия на панель управления
        barMain.add(actionFileView);
        barMain.add(actionExecute);
        barMain.add(actionCompil);
        barMain.add(actionFileImport);
        barMain.add(actionCreateFolder);
        barMain.add(actionFileRemove);
        barMain.add(actionUpdateRepository);
        barMain.add(actionDownload);
        btnConnect = barMain.add(actionConnect);
        btnDisconnect = barMain.add(actionLogoff);
        //barMain.add(actionFileSend);
        barMain.add(actionAbout);
        //добавить действия в меню
        menuFile.add(actionFileImport);
        menuFile.add(actionCreateFolder);
        menuFile.add(actionFileRemove);
        menuFile.add(actionUpdateRepository);
        menuFile.add(actionFileView);
		menuFile.add(actionExecute);
        menuFile.add(actionCompil);
        menuFile.add(actionDownload);
        menuFile.add(actionExit);

        menuLan.add(actionConnect);
        menuLan.add(actionLogoff);
        //menuLan.add(actionFileSend);
        
        menuHelp.add(actionAbout);
		// Обработчик смены кодировки
		encoding.addItemListener(new EncodingListener());
		paneTRight.getModel().addChangeListener( new TabListener());
        
        // Добавить действия в контекстное меню (от Richi)
        menuPopup.add(actionFileView);
        menuPopup.add(actionFileImport);
        menuPopup.add(actionCreateFolder);
        menuPopup.add(actionFileRemove);
        menuPopup.add(actionUpdateRepository);
        menuPopup.add(actionPaste);
    }
    /**
     * отобразить сообщение в поле "журнал"
     * @param message передаваемое сообщение
     */
    public void msg(String message){
        Date d=new Date();
        SimpleDateFormat dFormat = new SimpleDateFormat("HH:mm:ss");
        txtMsg.append("["+dFormat.format(d)+"] " + message+"\n");
    }
    
    /**
     * Отобразить текст в строке состояния
     * @param text текстовая трока
     */
    public void setStatusBarText(String text){
        lblStatusBar.setText(text);
    }
    /**
     * Allows to obtain extention part of filename
     * @param F spicifies File object
     * @return returns string containing extention
     */
    private String getExtentionFromFile(File F){
        String s[] = F.getName().split("\\.");
        int len = s.length;
        if (len < 2) return "";
        else return s[len - 1];
    }
    
    /**
     * Просмотр выбранного в списке файла. <br>
     * About way to choose encoding: all known bounds between encoding and file
     * extention are stored in ini-file. This info loads into JEncodingComboBox 
     * object when GFD created. But if there are some wrong lines in ini-file it 
     * can make exception inside this method while file is opening. So if this 
     * happends, file have to be opened with default encoding 'utf-16', and 
     * warning message is sending to Message text area ('Journal')
     * @return -1 в случае когда не выбран файл из списка, иначе 0
     *//*
    int fileView(){
        int sel = treeFiles.getSelectionRows()[0];
        String encd = "utf-16";
        Vector<File> importedFiles = innerLogic.getFiles();
        //игнорировать щелчки без выделения
        if(sel==-1 || importedFiles.size()==0) return -1;
        //прочитать файл и установить кодировку
        
        String extention = getExtentionFromFile(importedFiles.get(sel));
        try{
   //             encd = encoding.getEncodingBound(extention);
        } catch(Exception e){msg(e.getMessage());}
        try {
            char[] data = new char[(int)importedFiles.get(sel).length()];
            BufferedReader in;
            in = new BufferedReader(new java.io.InputStreamReader(
                    new java.io.FileInputStream(
                            importedFiles.get(sel)), encd));
            
            in.read(data);
            txtSource.setText(String.valueOf(data));
            //вывести содержимое
            curFile = importedFiles.get(sel);
            paneTRight.setTitleAt(0, curFile.getName());
        } catch (IOException ex) {
            msg("Невозможно прочитать файл "+importedFiles.get(sel).getPath());
        }
        encoding.setEnabled(true);
        return 0;
    }
*/
    /**
     * Установить картинку статуса соединения (левый нижний угол) и
     * скрыть (показать) кнопки соединения и разъединения на панели инструментов
     * @param flag true - соединение установлено, false - нет
     */
    public void setConnectStatus(boolean flag){
        if(flag) lblStatusBar.setIcon(new ImageIcon("pict/online_16.png"));
        else lblStatusBar.setIcon(new ImageIcon("pict/offline_16.png"));
        btnConnect.setVisible(!flag);
        btnDisconnect.setVisible(flag);
    }

    public void updateFileList(){
        Vector<File> importedFiles = innerLogic.getFiles();
        modeltreeFiles.clear();
        //заполнить список файлов
        for(int i=0;i<importedFiles.size();i++)
            modeltreeFiles.addElement(importedFiles.get(i).getName());
    }
    
     /**
     * @author Richi ID = 1017
     * Обработчик пункта контекстного меню "Вставка"
     */
    class PasteAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            msg("Данная команда еще не реализована.");
        }
    }    
}
